package com.atguigu.interpreter;

import java.util.HashMap;
import java.util.Stack;

/**
 * @program: design-patterns
 * @author: yangshen
 * @description:
 * @create: 2022-03-13 15:01
 **/
public class Calculator {
    /**
     * 定义表达式
     */
    private Expression expression;

    /**
     * 构造函数传参，并解析
     * @param expStr a+b
     */
    public Calculator(String expStr) {
        //安排运算先后顺序(通过 栈 来管理)
        Stack<Expression> stack = new Stack<>();
        //表达式拆分成字符数组 [a, +, b]
        char[] charArray = expStr.toCharArray();

        Expression left = null;
        Expression right = null;
        //遍历我们的字符数组，即遍历 [a, +, b]
        //针对不同的情况做处理
        for (int i = 0; i < charArray.length; i++) {
            switch (charArray[i]){
                case '+':
                    // 从stack取出left => "a"
                    left = stack.pop();
                    // 取出右表达式 "b"
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    // 然后根据得到left 和 right 构建 AddExpresson加入stack
                    stack.push(new AddExpression(left, right));
                    break;
                case '-':
                    // 从stack取出left => "a"
                    left = stack.pop();
                    // 取出右表达式 "b"
                    right = new VarExpression(String.valueOf(charArray[++i]));
                    // 然后根据得到left 和 right 构建 AddExpresson加入stack
                    stack.push(new SubExpression(left, right));
                    break;
                default:
                    //如果是一个var(a,b) 就创建要给 VarExpression 对象，并push到stack中
                    stack.push(new VarExpression(String.valueOf(charArray[i])));
                    break;
            }
        }
        //当遍历完整个 charArray 数组后，stack 就得到最后Expression（AddExpression或者SubExpression）
        this.expression =stack.pop();
    }

    public int run(HashMap<String, Integer> var){
        //最后将表达式a+b 和 var = {a=10, b=20}
        //然后传递给expression的interpreter执行
        return this.expression.interpreter(var);
    }



}
